<template>
	<view class="y-flex-1 position-relative">
		<web-view ref="webview" class="y-flex-1" src="/hybrid/html/my-picture-preview.html" @onPostMessage="handleMessage"></web-view>
		<view class="position-absolute left-0 right-0 bottom-0 border-top-1 border-top-style-dashed border-top-color-eee">
			<view class="y-flex y-row y-align-center y-justify-between page-padding-gap" style="height: 50px;">
				<com-icon :name="paused ? 'play_fill' : 'stop'" color="#fff" size="25px" @click="toggle"></com-icon>
				<com-icon name="camera" color="#fff" size="25px" @click="toAction"></com-icon>
				<com-icon :name="thumbsShow ? 'unfold' : 'fold'" color="#fff" size="25px" @click="thumbsShow = !thumbsShow"></com-icon>
				<com-icon name="share" color="#fff" size="25px" @click="toShare"></com-icon>
				<com-icon name="full" color="#fff" size="25px" @click="toFull"></com-icon>
			</view>
			<com-safe-bottom></com-safe-bottom>
		</view>
		<scroll-view
		class="position-absolute left-0 right-0 bg-000 pt-20 pb-20 pl-20 pr-20 y-flex y-row" style="bottom: 52px;height: 200rpx;"
		scroll-x
		scroll-with-animation
		:scroll-into-view="thumbId"
		:style="{'visibility': thumbsShow ? 'visible' : 'hidden'}">
			<view
			class="y-flex y-align-center y-justify-center border-1 border-color-eee position-relative"
			:class="{'mr-20': index < data.length-1}"
			:id="'thumb'+index"
			style="width: 300rpx;" v-for="(item, index) in data" :key="index" @tap="slideTo(index)">
				<text class="fs-40 fr-fff">{{index+1}}</text>
				<find-image
				class="position-absolute-cover"
				lazy-load
				:src="item.cover"
				mode="aspectFill"></find-image>
				<view class="position-absolute-cover bg-dark-mask" v-if="current != index"></view>
			</view>
		</scroll-view>
		<view class="position-absolute top-70 left-0 right-0 y-flex y-align-center y-justify-center" style="height: 75rpx;" v-if="data.length">
			<text class="fs-30 fr-fff pt-10 pb-10 pl-20 pr-20 bg-dark-mask border-radius-15">{{current+1}} / {{data.length}}</text>
		</view>
	</view>
</template>

<script>
	import { downloadNetResourceSaveLocal, base64ImageToLocalImage, shareFile, setWallpaper } from '@/assets/js/native.js'
	import FindImage from './Image.vue'
	export default {
		inject: ['download', 'toast', 'actionSheet'],
		components: {FindImage},
		computed: {
			network () {
				return this.$store.getters['network/GET']
			},
			globalConfig () {
				return this.network?.source?.globalConfig || {}
			},
			thumbId () {
				return 'thumb' + this.current
			}
		},
		data () {
			return {
				data: [],
				current: 0,
				paused: true,
				thumbsShow: false//展示缩略图
			}
		},
		methods: {
			handleMessage (e) {
				e.detail.data.forEach(item => {
					if ( item.change >= 0 ) {
						this.current = item.change
						this.$emit('change', {current: item.change, detail: this.data[item.change]})
					} else if ( item.error >= 0 ) {
						this.handleError(item.error)
					} else if ( item.timeListEnd >= 0 ) {
						this.setTimeList(item.timeListEnd)
					} else {
						Object.keys(item).forEach(key => {
							this.$emit(key, item[key])
						})
					}
				})
			},
			handleError(i) {
				const item = this.data[i]
				//查看图片是否有缓存
				const caches = this.$store.getters['cache/GET']
				const index = caches.findIndex(cache => cache.origin == item.src)
				//如果有缓存
				if ( index > -1 ) {
					//判断是否加载过缓存了，如果加载过了缓存，还报错，说明缓存路径已经失效了，需要重新加载
					if ( !item.isCache ) {
						item.url = caches[index].path
						item.tmpPath = caches[index].path
						item.isCache = true
						this.update(i, item)
						return
					} else {
						//删除已失效的缓存路径
						this.$store.dispatch('cache/remove', item.src)
					}
				}
				item.errorTime++
				//第一次加载错误，尝试获取图片解密方法
				if ( item.errorTime == 1 && item.src && this.globalConfig.imageDecrypt ) {
					this.network.$text(this.globalConfig.imageDecrypt, item.src, null).then(url => {
						if ( url.startsWith('data:image') ) {
							const format = url.match(/data:image\/*([\s\S]*?);base64,/)[1]
							const fileName = randomId() + '.' + (format || suffix(item.src))
							base64ImageToLocalImage(url, fileName).then(path => {
								item.url = path
								item.tmpPath = path
								this.update(i, item)
								//将图片路径存入缓存
								this.$store.dispatch('cache/add', {
									origin: item.src,
									path
								})
							}).catch(err => {
								this.handleError(i)
							})
						} else if ( url ) {
							item.url = url
							item.tmpPath = url
							this.update(i, item)
							this.$store.dispatch('cache/add', {
								origin: item.src,
								path: url
							})
						} else {
							this.handleError(i)
						}
					})
				} else item.errorTime++
				//第二次加载错误，尝试下载图片放在本地显示，因为加载错误可能是图片有防盗链的缘故
				if ( item.errorTime == 2 && item.src ) {
					const referer = item.referer ? item.referer : this.globalConfig.imageReferer ? this.globalConfig.imageReferer : this.network.baseUrl//获取图片referer
					downloadNetResourceSaveLocal({
						src: item.src,
						referer: referer,
						format: 'png',
						complete: res => {
							if ( res.errCode == 0 ) {
								item.url = res.tempFilePath
								item.tmpPath = res.tempFilePath
								this.update(i, item)
								//将图片路径存入缓存
								this.$store.dispatch('cache/add', {
									origin: item.src,
									path: res.tempFilePath
								})
							}
						}
					})
				}
			},
			toggle () {
				if ( this.paused ) this.play()
				else this.pause()
			},
			play () {
				this.paused = false
				this.$refs.webview && this.$refs.webview.evalJS(`play()`)
			},
			pause () {
				this.paused = true
				this.$refs.webview && this.$refs.webview.evalJS(`pause()`)
			},
			slideTo (current) {
				this.$refs.webview && this.$refs.webview.evalJS(`slideTo(${current})`)
			},
			//初始化
			init (data) {
				this.data = data.map(item => Object.assign({}, item, {isCache: false, errorTime: 0, url: item.src}))
				if ( this.data.length ) {
					this.setTimeList(0)
				}
			},
			setTimeList (index) {
				if ( index == this.data.length ) {
					this.$refs.webview && this.$refs.webview.evalJS(`init()`)
				} else {
					const list = this.data.slice(index, Math.min(index + 5, this.data.length))
					//数据需要转义2次，因为nvue的webview会自动转义一次
					this.$refs.webview && this.$refs.webview.evalJS(`setTimeList('${encodeURIComponent(encodeURIComponent(JSON.stringify(list)))}')`)
				}
			},
			//更新某一项数据
			update (current, data) {
				this.$set(this.data, current, data)
				this.$refs.webview && this.$refs.webview.evalJS(`update(${current}, '${encodeURIComponent(JSON.stringify(data))}')`)
			},
			//销毁
			destroy () {
				this.$refs.webview && this.$refs.webview.evalJS(`destroy()`)
			},
			getTmpPath (index) {
				uni.showLoading({
					title: '正在下载图片'
				})
				return new Promise((resolve, reject) => {
					const item = this.data[index]
					downloadNetResourceSaveLocal({
						src: item.src,
						referer: item.src,
						format: 'png',
						complete: res => {
							uni.hideLoading()
							if ( res.errCode == 0 ) {
								item.tmpPath = res.tempFilePath
								this.$set(this.data, index, item)
								//将图片路径存入缓存
								this.$store.dispatch('cache/add', {
									origin: item.src,
									path: res.tempFilePath
								})
								resolve(item.tmpPath)
							} else {
								reject(res.errMsg)
							}
						}
					})
				})
			},
			toAction () {
				this.actionSheet({
					title: '图片操作',
					data: ['保存至相册', '设为桌面壁纸', '设为锁屏壁纸', '设为桌面和锁屏壁纸'],//操作列表
					success: async res => {
						const item = this.data[this.current]
						if ( !item.src ) {
							uni.showToast({
								title: '请等待图片加载',
								icon: 'none'
							})
							return
						}
						//如果没有tmpPath说明还没有缓存临时文件，这里可以主动去下载
						try{
							if ( !item.tmpPath ) {
								await this.getTmpPath(this.current)
							}
							if ( res.current == 0 ) {
								uni.saveImageToPhotosAlbum({
									filePath: item.tmpPath,
									success: () => {
										this.toast('已保存到相册')
									},
									fail: () => {
										this.toast('保存到相册失败')
									}
								});
							} else {
								uni.showLoading({ title: '壁纸设置中' })
								setWallpaper(res.current == 1 ? 'wallpaper' : res.current == 2 ? 'lock' : 'all', item.tmpPath)
								uni.hideLoading()
							}
						}catch(e){
							this.toast(e.toString())
						}
					}
				})
			},
			async toShare () {
				const item = this.data[this.current]
				if ( !item.src ) {
					this.toast('未找到图片链接')
					return
				}
				//如果没有tmpPath说明还没有缓存临时文件，这里可以主动去下载
				try{
					if ( !item.tmpPath ) {
						await this.getTmpPath(this.current)
					}
					shareFile(item.tmpPath)
				}catch(e){
					this.toast(e.toString())
				}
			},
			toDownload () {
				const item = this.data[this.current]
				if ( !item.src ) {
					this.toast('未找到图片链接')
					return
				}
				this.download({title: item.title, url: item.src, isAdult: item.isAdult || 0})
			},
			toFull () {
				const item = this.data[this.current]
				if ( !item.src && !item.tmpPath ) {
					this.toast('未找到图片链接')
					return
				}
				uni.previewImage({
					urls: [item.tmpPath || item.src]
				})
			}
		}
	}
</script>

<style>
</style>